package handler

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	constants "go-admin1/internal/common/constant"
	"go-admin1/internal/common/utils"
	"go-admin1/internal/infrastructure/cache"
	"go-admin1/internal/infrastructure/captcha"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/mojocn/base64Captcha"
)

// CaptchaHandler 验证码控制器
type CaptchaHandler struct {
	captcha *base64Captcha.Captcha
}

// NewCaptchaHandler 创建验证码控制器实例
func NewCaptchaHandler() *CaptchaHandler {
	// 创建默认数字验证码配置
	driver := base64Captcha.NewDriverDigit(80, 240, 5, 0.7, 80)
	store := base64Captcha.DefaultMemStore
	captcha := base64Captcha.NewCaptcha(driver, store)

	return &CaptchaHandler{
		captcha: captcha,
	}
}

// CaptchaImage 获取验证码图片
func (h *CaptchaHandler) CaptchaImage(c *gin.Context) {

	// 保存验证码信息
	uuid := h.generateUUID()
	verifyKey := constants.CAPTCHA_CODE_KEY + uuid

	// 生成验证码
	captchaType := "math"
	var driver base64Captcha.Driver
	if "math" == captchaType {
		// 数学验证码驱动
		// 使用自定义数学验证码驱动
		customDriver := captcha.NewCustomDriverMath(80, 240, 0, 0, nil, nil)
		driver = customDriver
	} else if "char" == captchaType {
		// 字符验证码驱动
		driver = base64Captcha.NewDriverDigit(80, 240, 4, 0.7, 80)
	} else {
		// 默认字符验证码驱动
		driver = base64Captcha.NewDriverDigit(80, 240, 4, 0.7, 80)
	}

	// 创建验证码实例
	store := base64Captcha.DefaultMemStore
	captcha := base64Captcha.NewCaptcha(driver, store)

	// 生成验证码
	id, b64s, err := captcha.Generate()
	if err != nil {
		//return AjaxResult.Error(err.Error()), err

		return
	}

	// 存储到Redis
	cache.Set(verifyKey, id, time.Minute*5)

	// 转换图像为Base64
	//encodedImage := base64.StdEncoding.EncodeToString(image)

	c.JSON(http.StatusOK, gin.H{
		"code":           200,
		"msg":            "操作成功",
		"img":            b64s,
		"captchaEnabled": true,
		"uuid":           uuid,
	})
}

// generateUUID 生成UUID
func (h *CaptchaHandler) generateUUID() string {
	// 生成简单UUID的实现
	return h.simpleUUID()
}

// simpleUUID 生成简单UUID
func (h *CaptchaHandler) simpleUUID() string {
	// 使用Go的标准库生成UUID
	uuid := make([]byte, 16)
	_, err := rand.Read(uuid)
	if err != nil {
		// 如果随机数生成失败，使用时间戳作为备选方案
		return fmt.Sprintf("%d", time.Now().UnixNano())
	}

	// 设置UUID版本和变体
	uuid[6] = (uuid[6] & 0x0f) | 0x40
	uuid[8] = (uuid[8] & 0x3f) | 0x80

	return hex.EncodeToString(uuid)
}

// CaptchaImage 获取验证码图片
//func (h *CaptchaHandler) CaptchaImage(c *gin.Context) {
//	// 生成验证码
//	id, b64s, err := h.captcha.Generate()
//	if err != nil {
//		utils.FailResponse[string](c, "生成验证码失败")
//		return
//	}
//
//	// 返回验证码信息
//	resultData := map[string]interface{}{
//		"captchaId": id,
//		"image":     b64s,
//	}
//	utils.OkResponse(c, resultData)
//}

// VerifyCaptcha 验证验证码
func (h *CaptchaHandler) VerifyCaptcha(c *gin.Context) {
	var req struct {
		UUID string `json:"uuid" binding:"required"` // 使用UUID而不是ID
		Code string `json:"code" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.FailResponse[string](c, "参数错误")
		return
	}

	// 构造Redis键
	verifyKey := constants.CAPTCHA_CODE_KEY + req.UUID

	// 从Redis获取验证码ID
	captchaId, err := cache.Get(verifyKey)
	if err != nil || captchaId == "" {
		utils.FailResponse[string](c, "验证码已过期")
		return
	}

	// 使用默认存储验证验证码
	store := base64Captcha.DefaultMemStore
	if store.Verify(captchaId, req.Code, true) {
		// 验证成功后删除验证码
		cache.Delete(verifyKey)
		utils.OkResponseNoDataWithMessage[string](c, "验证码正确")
	} else {
		utils.FailResponse[string](c, "验证码错误")
	}
}
